package cn.lili.modules.order.cart.render.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SpringContextUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.store.client.StoreClient;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.urbansubstation.client.UrbanSubstationClient;
import cn.lili.modules.urbansubstation.entity.dos.UrbanSubstation;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 绿色积分分佣
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GreenScoreRender implements CartRenderStep {

    Map<SettingEnum, JSONObject> settings = new HashMap<>();

    private final UserClient userClient;

    private final UrbanSubstationClient urbanSubstationClient;

    private final StoreClient storeClient;

    private final GoodsClient goodsClient;
    @Override
    public RenderStepEnums step() {
        return RenderStepEnums.GREEN_SCORE;
    }

    @Override
    public void render(TradeDTO tradeDTO) {

        // 先把价格初始化一次，防止他人修改过
        initPrice(tradeDTO);
        initSetting();
        User currentUser = userClient.getById(tradeDTO.getMemberId());
        boolean isDistribution = currentUser != null && currentUser.getIsDistribution() != null && currentUser.getIsDistribution();
        tradeDTO.getCartList().forEach(cartVO -> {
            cartVO.getSkuList().forEach(cartSkuVO -> {
                if (CharSequenceUtil.isNotEmpty(cartSkuVO.getSupplierId())) {
                    User user = userClient.getByExtId(cartSkuVO.getSupplierId());
                    if (null != user && CharSequenceUtil.isNotEmpty(user.getUrbanSubstationId())) {
                        cartVO.setUrbanIdBySupplier(user.getUrbanSubstationId());
                        UrbanSubstation urbanSubstation = urbanSubstationClient.getUrbanSubstation(user.getUrbanSubstationId());
                        if (null != urbanSubstation) {
                            cartVO.setUrbanNameBySupplier(urbanSubstation.getUrbanName());
                        }
                    }
                }
                if (null != tradeDTO.getUserAddress() && CharSequenceUtil.isNotEmpty(tradeDTO.getUserAddress().getConsigneeAddressIdPath())) {
                    String[] areaIds = tradeDTO.getUserAddress().getConsigneeAddressIdPath().split(",");
                    for (String areaId : areaIds) {
                        UrbanSubstation urbanSubstation = urbanSubstationClient.getByAddressId(areaId);
                        if (null != urbanSubstation) {
                            cartVO.setUrbanIdByAddress(urbanSubstation.getUserId());
                            cartVO.setUrbanNameByAddress(urbanSubstation.getUrbanName());
                            break;
                        }
                    }
                }

            });
        });
        //初始化店主信息
        initParentId(tradeDTO);

        //如果存在分销员ID则不计算绿色积分分佣
        if(StringUtils.isEmpty(tradeDTO.getDistributionId())){
            tradeDTO.getCartList().forEach(cartVO -> {
                cartVO.getSkuList().forEach(cartSkuVO ->  {
                    if (null == cartSkuVO.getGoodsSku().getPromotionFlag() || !cartSkuVO.getGoodsSku().getPromotionFlag()) {
                        // 1.省级区域订单绿色积分分佣 暂时不分，等做了省级再分
//                    if(CharSequenceUtil.isNotEmpty(cartVO.getUrbanIdByAddress())) {
//                        cartSkuVO.getPriceDetailDTO().setSiteAddressGreenScore(mulPrice(
//                                cartSkuVO,
//                                CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()) - CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
//                                settings.get(SettingEnum.GREEN_GOODS).getDouble("agentAddressProportion"),
//                                settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("agentAddressProportion")
//                        ));
//                    }
                        // 2.市级区域订单分佣 收货地址所在城市站点
                        if(CharSequenceUtil.isNotEmpty(cartVO.getUrbanIdByAddress())) {
                            cartSkuVO.getPriceDetailDTO().setSiteAddressGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()) - CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("agentAddressProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("agentAddressProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setSiteAddressGreenScore(0.0);
                            }
                        }
                        //3.直销商家供货订单分佣 城市站点绿色积分分佣计算
                        if (CharSequenceUtil.isNotEmpty(cartVO.getUrbanIdBySupplier())) {
                            cartSkuVO.getPriceDetailDTO().setSiteGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("agentProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("agentProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setSiteGreenScore(0.0);
                            }
                        }
                        // 4.工会绿色积分分佣,如果开启一级分佣,则不分佣
                        if (StringUtils.isNotEmpty(tradeDTO.getLowerCommissId()) && (cartSkuVO.getGoodsSku().getIsLevelDistribution() == null || !cartSkuVO.getGoodsSku().getIsLevelDistribution())) {
                            cartSkuVO.getPriceDetailDTO().setUnionGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("unionProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("unionProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setUnionGreenScore(0.0);
                            }
                        }
                        if (StringUtils.isNotEmpty(tradeDTO.getLowerCommissId()) && (cartSkuVO.getGoodsSku().getIsLevelDistribution() == null || !cartSkuVO.getGoodsSku().getIsLevelDistribution())) {
                            // 5.城主绿色积分分佣,如果开启一级分佣,则不分佣
                            cartSkuVO.getPriceDetailDTO().setCastellanGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("castellanProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("castellanProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setCastellanGreenScore(0.0);
                            }
                        }
                        // 6.上推佣金（店主-下级用户订单分佣）
                        if(StringUtils.isNotEmpty(tradeDTO.getLowerCommissId())){
                            if(tradeDTO.getIsDistribution()){
                                cartSkuVO.getPriceDetailDTO().setLowerGreenScore(mulPrice(
                                        cartSkuVO,
                                        CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                        settings.get(SettingEnum.GREEN_GOODS).getDouble("lowerSubProportion"),
                                        settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("lowerSubProportion")
                                ));
                            }else{
                                if (cartSkuVO.getGoodsSku() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                    //开启一级分销,直接返佣 sku的绿色积分值
                                    cartSkuVO.getPriceDetailDTO().setLowerGreenScore(cartSkuVO.getGoodsSku().getGreenScore() * cartSkuVO.getNum());
                                } else {
                                    cartSkuVO.getPriceDetailDTO().setLowerGreenScore(mulPrice(
                                            cartSkuVO,
                                            CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                            settings.get(SettingEnum.GREEN_GOODS).getDouble("lowerProportion"),
                                            settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("lowerProportion")
                                    ));
                                }
                            }
                        }

                        // 7.间推佣金（店主-间推用户订单分佣）,如果开启一级分佣,则不分佣
                        if (StringUtils.isNotEmpty(tradeDTO.getLowerCommissId()) && !tradeDTO.getIsDistribution() && (cartSkuVO.getGoodsSku().getIsLevelDistribution() == null || !cartSkuVO.getGoodsSku().getIsLevelDistribution())) {
                            cartSkuVO.getPriceDetailDTO().setLowerSubGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("lowerSubProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("lowerSubProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setLowerSubGreenScore(0.0);
                            }
                        }
                        // 8.店铺获得的绿色积分分佣（店铺） 商铺分佣计算
                        if(CharSequenceUtil.isNotEmpty(cartVO.getStoreId()) && !cartVO.getStoreId().equals("-1")) {
                            cartSkuVO.getPriceDetailDTO().setStoreGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("storeProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("storeProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setStoreGreenScore(0.0);
                            }
                        }
                        // 9.用户获得的绿色积分分佣（用户） 用户购买返佣计算
                        cartSkuVO.getPriceDetailDTO().setMemberGreenScore(mulPrice(
                                cartSkuVO,
                                CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                settings.get(SettingEnum.GREEN_GOODS).getDouble("userProportion"),
                                settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("userProportion")
                        ));
                        //开启一级分佣,则不分
                        if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                            cartSkuVO.getPriceDetailDTO().setMemberGreenScore(0.0);
                        }
                        // 10.绿色公益分佣（公益） 公益商品才参与公益分佣
                        if (cartSkuVO.getIsCommonwealGoods()) {
                            // 绿色公益投放百分比分佣
                            cartSkuVO.getPriceDetailDTO().setGreenCommonwealGreenScore(mulPrice(
                                    cartSkuVO,
                                    CurrencyUtil.sub(CurrencyUtil.mul(cartSkuVO.getGoodsSku().getGreenScore(), cartSkuVO.getNum()), CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)),
                                    settings.get(SettingEnum.GREEN_GOODS).getDouble("commonwealProportion"),
                                    settings.get(SettingEnum.NOT_GREEN_GOODS).getDouble("commonwealProportion")
                            ));
                            //开启一级分佣,则不分
                            if (cartSkuVO.getGoodsSku().getIsLevelDistribution() != null && cartSkuVO.getGoodsSku().getIsLevelDistribution()) {
                                cartSkuVO.getPriceDetailDTO().setGreenCommonwealGreenScore(0.0);
                            }
                        }
                    }
                });
            });
        }


        // 每个子购物车计算绿色积分分佣
//        tradeDTO.getCartList().forEach(cartVO -> cartVO.getSkuList().forEach(cartSkuVO -> cartSkuVO.getPriceDetailDTO().recountGreenScore()));
        // 把子商品的价格累加到上层子购物车中
        buildCartPrice(tradeDTO);
        // 把子购物车中的价格合并到合并订单中
        buildTradePrice(tradeDTO);
        // 计算最终用户支付金额
        buildFlowPrice(tradeDTO);

        System.out.println("绿色积分计算完成");
        System.out.println(JSONObject.toJSONString(tradeDTO));
    }

    /**
     * 构建店主信息
     * */
    private void initParentId(TradeDTO tradeDTO){
        //设置直推店主
        User parentUser = userClient.getById(tradeDTO.getMemberId());
        log.info("tradeDTO.getMemberId()-->>",tradeDTO.getMemberId());
        log.info("parentUser.getParentId()-->>",parentUser.getParentId());
        String lowerCommissId = parentUser.getParentId();
        //当前用户身份
        Boolean isDistribution = parentUser.getIsDistribution() != null && parentUser.getIsDistribution();
        //设置间推店主
        String lowerSubCommiss = null;
        if(StringUtils.isNotEmpty(lowerCommissId)){
            User parentParentUser = userClient.getById(lowerCommissId);
            lowerSubCommiss  = parentParentUser!=null?parentParentUser.getParentId():null;
        }
        //构建到tradeDTO
        tradeDTO.setLowerCommissId(StringUtils.isNotEmpty(lowerCommissId)?lowerCommissId:null);
        tradeDTO.setLowerSubCommissId(lowerSubCommiss);

        //如果是一级分销商品,则把间推id设置为null
        if (CollUtil.isNotEmpty(tradeDTO.getCheckedSkuList())) {
            for (CartSkuVO cartSkuVO : tradeDTO.getCheckedSkuList()) {
                if (cartSkuVO.getGoodsSku() != null) {
                    Goods goods = goodsClient.getById(cartSkuVO.getGoodsSku().getGoodsId());
                    //StoreVO storeVO = storeClient.getStore(cartSkuVO.getGoodsSku().getStoreId());
//                    if (storeVO != null && storeVO.getIsGiftStore() != null && storeVO.getIsGiftStore()) {
                    //店主购买，直推/间推不分佣
                    if (isDistribution && goods != null && goods.getIsLevelDistribution() != null && goods.getIsLevelDistribution()) {
                        tradeDTO.setLowerCommissId(null);
                        tradeDTO.setLowerSubCommissId(null);

                        break;
                    } else if (goods != null && goods.getIsLevelDistribution() != null && goods.getIsLevelDistribution()) {
                        tradeDTO.setLowerSubCommissId(null);
                        break;
                    }
                }
            }
        }
        tradeDTO.setIsDistribution(isDistribution);
        log.info("lowerCommissId-->>",lowerCommissId);
    }

    // 重新计算用户需要支付的金额
    private void buildFlowPrice(TradeDTO tradeDTO){
        tradeDTO.getCartList().forEach(cartVO -> {
            cartVO.getSkuList().forEach(cartSkuVO -> {
                System.out.println(cartSkuVO.getPriceDetailDTO());
                System.out.println(cartSkuVO.getPriceDetailDTO().getFmoney());
                cartSkuVO.getPriceDetailDTO()
                        .setFlowPrice(CurrencyUtil.sub(CurrencyUtil.add(
                                cartSkuVO.getPriceDetailDTO().getFlowPrice(),
                                        cartSkuVO.getPriceDetailDTO().getGreenScore())
                                , CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getFmoney(), 10)));
                System.out.println(cartSkuVO.getPriceDetailDTO());
            });
        });

        tradeDTO.getCartList().forEach(cartVO -> {
            cartVO.getPriceDetailDTO().setFlowPrice(0D);
            cartVO.getPriceDetailDTO().accumulationFlowPriceDTO(
                    cartVO.getSkuList().stream().map(CartSkuVO::getPriceDetailDTO).toList()
            );
        });

        tradeDTO.getPriceDetailDTO().setFlowPrice(0D);
        tradeDTO.getPriceDetailDTO().accumulationFlowPriceDTO(
                tradeDTO.getCartList().stream().map(CartVO::getPriceDetailDTO).toList());
        System.out.println(tradeDTO.getPriceDetailDTO());
    }

    private void initSetting(){
        SettingClient settingClient = SpringContextUtil.getBean(SettingClient.class);

        JSONObject greenGoodsSetting = JSONObject.parseObject(settingClient.get(SettingEnum.GREEN_GOODS.name()).getSettingValue());
        JSONObject goodsSetting = JSONObject.parseObject(settingClient.get(SettingEnum.NOT_GREEN_GOODS.name()).getSettingValue());

        settings.put(SettingEnum.GREEN_GOODS, greenGoodsSetting);
        settings.put(SettingEnum.NOT_GREEN_GOODS, goodsSetting);
    }

    /**
     * 根据绿色商品和非绿色商品进行计算佣金
     * @param cartSkuVO
     * @param price
     * @param rate1
     * @param rate2
     * @return
     */
    private Double mulPrice(CartSkuVO cartSkuVO, Double price, Double rate1, Double rate2){
        if(Boolean.TRUE.equals(cartSkuVO.getIsGreenGoods())) {
            return CurrencyUtil.div(CurrencyUtil.mul(price, rate1 == null ? 0D : rate1), 100);
        }else {
            return CurrencyUtil.div(CurrencyUtil.mul(price, rate2 == null ? 0D : rate2), 100);
        }
    }

    /**
     * 初始化
     * @param tradeDTO
     */
    private void initPrice(TradeDTO tradeDTO){
        tradeDTO.getPriceDetailDTO().setStoreGreenScore(0D);
        tradeDTO.getPriceDetailDTO().setSupplierGreenScore(0D);
        tradeDTO.getPriceDetailDTO().setMemberGreenScore(0D);
        tradeDTO.getPriceDetailDTO().setSiteGreenScore(0D);
    }



    /**
     * 初始化购物车
     *
     * @param tradeDTO 购物车展示信息
     */
    void buildTradePrice(TradeDTO tradeDTO) {
        tradeDTO.getPriceDetailDTO().accumulationGreenPriceDTO(
                tradeDTO.getCartList().stream().map(CartVO::getPriceDetailDTO).toList());
    }

    private void buildCartPrice(TradeDTO tradeDTO){
        tradeDTO.getCartList().forEach(cartVO -> {
            cartVO.getPriceDetailDTO().accumulationGreenPriceDTO(
                    cartVO.getSkuList().stream().map(CartSkuVO::getPriceDetailDTO).toList()
            );
        });
    }
}
